package com.rainbow.redis.plus.core.metrics;

import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;

import com.rainbow.qps.FlowHelper;
import com.rainbow.qps.FlowType;
import com.rainbow.qps.Flower;
import com.rainbow.redis.plus.core.constant.RedisConstant;

import io.micrometer.core.instrument.Gauge;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.binder.MeterBinder;

public class RedisPlusMetrics implements MeterBinder {

	@Autowired(required = false)
	private FlowHelper flowHelper;
	
	@Autowired
    private Environment environment;

	@Override
	public void bindTo(MeterRegistry registry) {
		if (flowHelper == null) {
			return;
		}

		Map<FlowType, Flower> flowMap = flowHelper.getFlowMap();
		for (Map.Entry<FlowType, Flower> entry : flowMap.entrySet()) {
			builder(entry.getKey(),entry.getValue(),registry);
		}
		
		String projectName = environment.getProperty(RedisConstant.PROJECT_NAME, String.class, RedisConstant.UNKNOWN);
		String projectUUID = environment.getProperty(RedisConstant.PROJECT_UUID, String.class, RedisConstant.UNKNOWN);
		
		Gauge.builder("redis.plus.project.name", 0, (l) -> {
			return 0;
		}).tag("target", projectName)
		.description("监控微服务实例项目名称")
		.register(registry);
		
		Gauge.builder("redis.plus.project.id", 0, (l) -> {
			return 0;
		}).tag("target", projectUUID)
		.description("监控微服务实例项目实例")
		.register(registry);
	}

	private void builder(FlowType flowType ,Flower flower,MeterRegistry registry) {
		if (flower == null) {
			return;
		}
		String name = flowType.name().toLowerCase();
		String dec = "";
		if (flowType == FlowType.Second) {
			dec = "秒";
		}else if (flowType == FlowType.Minute) {
			dec = "分";
		}else if (flowType == FlowType.Hour) {
			dec = "时";
		}
		
		String reqName = "redis.plus." + name +".req";
		String rtName = "redis.plus." + name +".rt";
		
		// 【请求数】
		Gauge.builder(reqName, flower, (f) -> {
			return f.total();
		}).tag("target", "total")
		.description("监控微服务实例的请求数 -> 每" + dec +"【total请求数,totalSuccess成功数,totalException异常数,successAvg平均成功数(对于Hour Type就是平均每分钟,对于Minute Type就是平均每秒,对于Second Type就是平均每毫秒),exceptionAvg平均异常数】")
		.register(registry);

		// 【成功数】
		Gauge.builder(reqName, flower, (f) -> {
			return f.totalSuccess();
		}).tag("target", "totalSuccess").register(registry);

		// 【异常数】
		Gauge.builder(reqName, flower, (f) -> {
			return f.totalException();
		}).tag("target", "totalException").register(registry);

		// 【平均成功数】
		Gauge.builder(reqName, flower, (f) -> {
			return f.successAvg();
		}).tag("target", "successAvg").register(registry);

		// 【平均异常数】
		Gauge.builder(reqName, flower, (f) -> {
			return f.exceptionAvg();
		}).tag("target", "exceptionAvg").register(registry);

		// 【最大耗时】
		Gauge.builder(rtName, flower, (f) -> {
			return f.maxRt();
		}).tag("target", "maxRt").description("监控微服务实例的请求耗时 -> 每"+ dec +"【maxRt最大耗时,minRt最小耗时,avgRt平均耗时】").register(registry);

		// 【最小耗时】
		Gauge.builder(rtName, flower, (f) -> {
			return f.minRt();
		}).tag("target", "minRt").register(registry);

		// 【平均耗时】
		Gauge.builder(rtName, flower, (f) -> {
			return f.avgRt();
		}).tag("target", "avgRt").register(registry);
	}

}
